using UnityEngine;
using System.Collections;

[AddComponentMenu("LWS/Controls/Circle Progress Bar Ext")]
public class lwEZUICircleProgressBar : lwEZUIProgressBar
{
	private bool[] ColorOverride = new bool[]{false,false};
	public bool OverrideEmptyColor
	{
		get{return ColorOverride[0];}
		set
		{
			if (ColorOverride[0] != value)
			{
				ColorOverride[0] = value;
				UpdateMesh();
			}
		}
	}
	public bool OverrideFilledColor
	{
		get { return ColorOverride[1]; }
		set
		{
			if(ColorOverride[1] != value)
			{
				ColorOverride[1] = value;
				UpdateMesh();
			}
		}
	}

	private Color[] m_Color = new Color[]{Color.white,Color.white};

	public Color EmptyColorOverride
	{
		get { return m_Color[0]; }
		set
		{
			if( m_Color[0] != value )
			{
				m_Color[0] = value;
				UpdateMesh();
			}
		}
	}

	public Color FilledColorOverride
	{
		get { return m_Color[1]; }
		set
		{
			if (m_Color[1] != value)
			{
				m_Color[1] = value;
				UpdateMesh();
			}
		}
	}

	public int subdivision = 16;
	private MeshFilter[] m_MeshFilter = null;
	private MeshRenderer[] m_MeshRenderer = null;
	private Mesh[] m_Mesh = null;

	private Vector3[][] m_Vertices = null;
	private Vector2[][] m_UVs = null;
	private Color[][] m_Colors = null;
	private int[][] m_Triangles = null;

	private AutoSpriteBase[] m_AutoSp = null;
	private GameObject[] m_Go = null;
	private void InitMesh()
	{
		if (m_MeshFilter == null )
		{
			m_MeshFilter = new MeshFilter[2];
			m_MeshRenderer = new MeshRenderer[2];
			m_Mesh = new Mesh[2];

			m_Vertices = new Vector3[2][] { new Vector3[subdivision + 2], new Vector3[subdivision + 2] };
			m_UVs = new Vector2[2][] { new Vector2[subdivision + 2], new Vector2[subdivision + 2] };
			m_Colors = new Color[2][] { new Color[subdivision + 2], new Color[subdivision + 2] };
			m_Triangles = new int[2][] { new int[subdivision * 3], new int[subdivision * 3] };

			m_Go = new GameObject[2];
			m_Go[0] = new GameObject("EmptyCircle");
			m_Go[1] = new GameObject("FilledCircle");

			m_AutoSp = new AutoSpriteBase[2];
			m_AutoSp[0] = emptySprite;
			m_AutoSp[1] = this;

			for (int i = 0; i < 2; ++i)
			{
				m_Go[i].transform.parent = transform;
				m_Go[i].transform.localPosition = Vector3.zero;
				m_Go[i].transform.localRotation = Quaternion.identity;
				m_Go[i].transform.localScale = Vector3.one;
				m_MeshFilter[i] = m_Go[i].AddComponent<MeshFilter>();
				m_MeshRenderer[i] = m_Go[i].AddComponent<MeshRenderer>();
				m_Mesh[i] = new Mesh();
				m_MeshFilter[i].mesh = m_Mesh[i];

				m_AutoSp[i].UpdateUVs();
				m_MeshRenderer[i].sharedMaterial = m_AutoSp[i].GetComponent<MeshRenderer>().sharedMaterial;
				for (int vtx = 0; vtx < subdivision; ++vtx)
				{
					m_Triangles[i][3 * vtx + 0] = 0;
					m_Triangles[i][3 * vtx + 1] = vtx + 2;
					m_Triangles[i][3 * vtx + 2] = vtx + 1;
				}
			}
			UpdateMesh();
			Hide(IsHidden());
		}
	}

	private float internalValue = -1.0f;

	protected override void UpdateProgress()
	{
		base.UpdateProgress();
		if (!Mathf.Approximately(internalValue, m_value))
		{
			internalValue = m_value;
			UpdateMesh();
		}
	}
	
	void UpdateMesh()
	{
		if(!Application.isPlaying || emptySprite==null )
			return;
	
		if (m_MeshFilter == null)
		{
			InitMesh();
		}

		Vector3[][] verticesAutoSp = new Vector3[2][] { m_AutoSp[0].spriteMesh.vertices, m_AutoSp[1].spriteMesh.vertices};
		
		Vector3 minVtx = verticesAutoSp[1][1];
		Vector3 maxVtx = verticesAutoSp[0][3];

		Vector3 centerVtx = (minVtx + maxVtx) / 2.0f;

		// center Vertex is centered
		for( int i = 0; i<2; ++i )
		{
			SPRITE_FRAME spriteFrame = m_AutoSp[i].animations[0].GetCurrentFrame();

			Vector2 minUv = new Vector2(spriteFrame.uvs.xMin, spriteFrame.uvs.yMin);
			Vector2 maxUv = new Vector2(spriteFrame.uvs.xMax, spriteFrame.uvs.yMax);
			Vector2 centerUv = (minUv + maxUv) / 2.0f;

			//angle of a triangle is m_FillRatio*2*PI/subdivision --> m_FillRatio*Pi/(subdivision/2)
			float fStartAngle = (i == 0) ? (0) : ((1 - Value) * Mathf.PI * 2.0f);
			float fDeltaAngle = ((i == 0) ? (1-Value) : (Value)) * Mathf.PI / (subdivision / 2.0f);

			m_Vertices[i][0] = Vector3.zero;
			m_UVs[i][0] = centerUv;
			m_Colors[0][0] = ColorOverride[0] ? m_Color[0] : m_AutoSp[0].Color;
			m_Colors[1][0] = ColorOverride[1] ? m_Color[1] : m_AutoSp[1].Color;
			for (int vtx = 1; vtx < subdivision + 2; ++vtx)
			{
				m_Colors[i][vtx] = ColorOverride[i]?m_Color[i]:m_AutoSp[i].Color;

				float fAngle = fStartAngle + fDeltaAngle * (vtx - 1);
				float ratioX = (Mathf.Sin(-fAngle) + 1.0f) / 2.0f;
				float ratioY = (Mathf.Cos(-fAngle) + 1.0f) / 2.0f;


				m_Vertices[i][vtx] = new Vector3(Mathf.Lerp(minVtx.x, maxVtx.x, ratioX), Mathf.Lerp(minVtx.y, maxVtx.y, ratioY), 0) - centerVtx;
				m_UVs[i][vtx] = new Vector2(Mathf.Lerp(minUv.x, maxUv.x, ratioX), Mathf.Lerp(minUv.y, maxUv.y, ratioY));
			}

			m_Mesh[i].vertices = m_Vertices[i];
			m_Mesh[i].colors = m_Colors[i];
			m_Mesh[i].uv = m_UVs[i];
			m_Mesh[i].SetTriangles(m_Triangles[i], 0);

			m_Mesh[i].Optimize();

			m_MeshFilter[i].mesh = m_Mesh[i];
			m_MeshRenderer[i].material = m_AutoSp[i].GetComponent<MeshRenderer>().sharedMaterial;
		}
		
	}

	public override void Hide(bool tf)
	{
		base.Hide(tf);

		renderer.enabled = false;
		if (emptySprite != null)
			emptySprite.renderer.enabled = false;
		if ( m_MeshRenderer != null )	
			foreach( MeshRenderer mrd in m_MeshRenderer)
				mrd.enabled = !tf;
	}
		
	public override Camera RenderCamera
	{
		get { return renderCamera; }
		
		set { 
			base.RenderCamera = value;
			
			if (emptySprite != null)
				emptySprite.RenderCamera = value;
		}
	}
	
	public override void SetCamera(Camera c)
	{
		base.SetCamera(c);
		
		if (emptySprite != null)
			emptySprite.SetCamera(c);
	}
}
